package gu.jimgutil;
/**
 * 图像矩阵色彩空间转换<br>
 * 如果成功加载native library,则调用{@link CsCvtNativeImpl}中的native 方法，否则调用{@link CsCvtUniImpl}对应的方法
 * @author guyadong
 *
 */
public class MatrixUtils {
	/**
	 * 将输入图像的色彩空间RGBA转为BGR
	 * @param input 输入图像矩阵RGBA,size=stride*height
	 * @param width 图像宽度
	 * @param height 图像宽度
	 * @return 输出图像,size=width*height*3
	 * @throws NullPointerException 
	 * @throws IllegalArgumentException
	 * @deprecated instead use {@link #RGB2BGR(byte[], int, int, int)}
	 */
	public static byte[] RGBA2BGR(byte[] input,int width,int height) 
			throws NullPointerException, IllegalArgumentException{
		return RGBA2BGR(input,width,height,width*4);
	}
	/**
	 * 将输入图像的色彩空间RGBA转为BGR
	 * @param input 输入图像矩阵RGBA,size=stride*height
	 * @param width 图像宽度
	 * @param height 图像宽度
	 * @param stride 步长(每行像素字节数)
	 * @return 输出图像,size=width*height*3
	 * @throws NullPointerException
	 * @throws IllegalArgumentException
	 */
	public static byte[] RGBA2BGR(byte[] input,int width,int height,int stride) 
			throws NullPointerException, IllegalArgumentException{
		byte[] output = new byte[width*height*3];
		RGBA2BGR(input,width,height,stride,output);
		return output;
	}
	/**
	 * 将输入图像的色彩空间RGBA转为BGR
	 * @param input 输入图像矩阵RGBA,size=stride*height
	 * @param width 图像宽度
	 * @param height 图像宽度
	 * @return 输出图像,size=width*height*3
	 * @throws NullPointerException 
	 * @throws IllegalArgumentException
	 * @deprecated instead use {@link #RGBA2RGB(byte[], int, int, int)}
	 */
	public static byte[] RGBA2RGB(byte[] input,int width,int height) 
			throws NullPointerException, IllegalArgumentException{
		return RGBA2RGB(input,width,height,width*4);
	}
	/**
	 * 将输入图像的色彩空间RGBA转为BGR
	 * @param input 输入图像矩阵RGBA,size=stride*height
	 * @param width 图像宽度
	 * @param height 图像宽度
	 * @param stride 步长(每行像素字节数)
	 * @return 输出图像,size=width*height*3
	 * @throws NullPointerException
	 * @throws IllegalArgumentException
	 */
	public static byte[] RGBA2RGB(byte[] input,int width,int height,int stride) 
			throws NullPointerException, IllegalArgumentException{
		byte[] output = new byte[width*height*3];
		RGBA2RGB(input,width,height,stride,output);
		return output;
	}
	/**
	 * 将输入图像的色彩空间RGBA转为灰度图像
	 * @param input 输入图像矩阵RGBA,size=stride*height
	 * @param width 图像宽度
	 * @param height 图像宽度
	 * @return 输出图像,size=width*height
	 * @throws NullPointerException 
	 * @throws IllegalArgumentException
	 * @deprecated instead use {@link #RGBA2GRAY(byte[], int, int, int)}
	 */
	public static byte[] RGBA2GRAY(byte[] input,int width,int height) 
			throws NullPointerException, IllegalArgumentException{
		return RGBA2GRAY(input,width,height,width*4);
	}
	/**
	 * 将输入图像的色彩空间RGBA转为灰度图像
	 * @param input 输入图像矩阵RGBA,size=stride*height
	 * @param width 图像宽度
	 * @param height 图像宽度
	 * @param stride 步长(每行像素字节数)
	 * @return 输出图像,size=width*height
	 * @throws NullPointerException
	 * @throws IllegalArgumentException
	 */
	public static byte[] RGBA2GRAY(byte[] input,int width,int height,int stride) 
			throws NullPointerException, IllegalArgumentException{
		byte[] output = new byte[width*height];
		RGBA2GRAY(input,width,height,stride,output);
		return output;
	}
	/**
	 * 将输入图像的色彩空间RGB转为BGR
	 * @param input 输入图像矩阵RGB,size=stride*height
	 * @param width 图像宽度
	 * @param height 图像宽度
	 * @return 输出图像,size=width*height*3
	 * @throws NullPointerException 
	 * @throws IllegalArgumentException
	 * @deprecated instead use {@link #RGB2BGR(byte[], int, int, int)}
	 */
	public static byte[] RGB2BGR(byte[] input,int width,int height) 
			throws NullPointerException, IllegalArgumentException{
		return RGB2BGR(input,width,height,width*3);
	}
	/**
	 * 将输入图像的色彩空间RGB转为BGR
	 * @param input 输入图像矩阵RGB,size=stride*height
	 * @param width 图像宽度
	 * @param height 图像宽度
	 * @param stide 步长(每行像素字节数)
	 * @return 输出图像,size=width*height*3
	 * @throws NullPointerException 
	 * @throws IllegalArgumentException
	 */
	public static byte[] RGB2BGR(byte[] input,int width,int height,int stride) 
			throws NullPointerException, IllegalArgumentException{
		byte[] output = new byte[width*height*3];
		RGB2BGR(input,width,height,stride,output);
		return output;
	}
	/**
	 * 将输入图像的色彩空间RGB转为灰度
	 * @param input 输入图像矩阵RGB,size=stride*height
	 * @param width 图像宽度
	 * @param height 图像宽度
	 * @return 输出图像,size=width*height
	 * @throws NullPointerException 
	 * @throws IllegalArgumentException
	 * @deprecated instead use {@link #RGB2GRAY(byte[], int, int, int)}
	 */
	public static byte[] RGB2GRAY(byte[] input,int width,int height) 
			throws NullPointerException, IllegalArgumentException{
		return RGB2GRAY(input,width,height,width);
	}
	/**
	 * 将输入图像的色彩空间RGB转为灰度
	 * @param input 输入图像矩阵RGB,size=stride*height
	 * @param width 图像宽度
	 * @param height 图像宽度
	 * @param stride 步长(每行像素字节数)
	 * @return 输出图像,size=width*height
	 * @throws NullPointerException 
	 * @throws IllegalArgumentException
	 */
	public static byte[] RGB2GRAY(byte[] input,int width,int height,int stride) 
			throws NullPointerException, IllegalArgumentException{
		byte[] output = new byte[width*height];
		RGB2GRAY(input,width,height,stride,output);
		return output;
	}
	/**
	 * 将输入图像的色彩空间BGR转为RGBA
	 * @param input 输入图像矩阵RGBA,size=stride*height
	 * @param width 图像宽度
	 * @param height 图像宽度
	 * @param stride 步长(每行像素字节数)
	 * @return 输出图像,size=width*height*4
	 * @throws NullPointerException
	 * @throws IllegalArgumentException
	 */
	public static byte[] BGR2RGBA(byte[] input,int width,int height,int stride) 
			throws NullPointerException, IllegalArgumentException{
		byte[] output = new byte[width*height*4];
		BGR2RGBA(input,width,height,stride,output);
		return output;
	}
	/**
	 * 将输入图像的色彩空间BGR转为RGBA
	 * @param input 输入图像矩阵RGBA,size=stride*height
	 * @param width 图像宽度
	 * @param height 图像宽度
	 * @param stride 步长(每行像素字节数)
	 * @return 输出图像,size=width*height*4
	 * @throws NullPointerException
	 * @throws IllegalArgumentException
	 */
	public static byte[] RGB2RGBA(byte[] input,int width,int height,int stride) 
			throws NullPointerException, IllegalArgumentException{
		byte[] output = new byte[width*height*4];
		RGB2RGBA(input,width,height,stride,output);
		return output;
	}
	/**
	 * 将输入图像的色彩空间RGBA转为BGR，输出到output
	 * @param input 输入图像矩阵RGBA,size=stride*height
	 * @param width 图像宽度
	 * @param height 图像宽度
	 * @param stride 每行步长(字节长度),必须>= width*4
	 * @param output [out] 输出图像,size=width*height*3
	 * @throws NullPointerException 
	 * @throws IllegalArgumentException
	 */
	public static void RGBA2BGR(byte[] input,int width,int height,int stride,byte[] output) 
			throws NullPointerException, IllegalArgumentException{
		if(CsCvtNativeImpl.isNativeLoaded()){
			CsCvtNativeImpl.RGBA2BGR(input, width, height, stride, output);
		}else{
			CsCvtUniImpl.RGBA2BGR(input, width, height, stride, output);
		}
	}
	/**
	 * 将输入图像的色彩空间RGBA转为RGB，输出到output
	 * @param input 输入图像矩阵RGBA,size=stride*height
	 * @param width 图像宽度
	 * @param height 图像宽度
	 * @param stride 每行步长(字节长度),必须>= width*4
	 * @param output [out] 输出图像,size=width*height*3
	 * @throws NullPointerException 
	 * @throws IllegalArgumentException
	 */
	public static void RGBA2RGB(byte[] input,int width,int height,int stride,byte[] output) 
			throws NullPointerException, IllegalArgumentException{
		if(CsCvtNativeImpl.isNativeLoaded()){
			CsCvtNativeImpl.RGBA2RGB(input, width, height, stride, output);
		}else{
			CsCvtUniImpl.RGBA2RGB(input, width, height, stride, output);
		}
	}
	/**
	 * 将输入图像的色彩空间RGBA转为灰度，输出到output
	 * @param input 输入图像矩阵RGBA,size=stride*height
	 * @param width 图像宽度
	 * @param height 图像宽度
	 * @param stride 每行步长(字节长度),必须>= width*4
	 * @param output [out] 输出图像,size=width*height
	 * @throws NullPointerException 
	 * @throws IllegalArgumentException
	 */
	public static void RGBA2GRAY(byte[] input,int width,int height,int stride,byte[] output) 
			throws NullPointerException, IllegalArgumentException{
		if(CsCvtNativeImpl.isNativeLoaded()){
			CsCvtNativeImpl.RGBA2GRAY(input, width, height, stride, output);
		}else{
			CsCvtUniImpl.RGBA2GRAY(input, width, height, stride, output);
		}
	}
	/**
	 * 将输入图像的色彩空间RGB转为BGR，输出到output
	 * @param input 输入图像矩阵RGB,size=stride*height
	 * @param width 图像宽度
	 * @param height 图像宽度
	 * @param stride 每行步长(字节长度),必须>= width*4
	 * @param output [out] 输出图像,size=width*height*3
	 * @throws NullPointerException 
	 * @throws IllegalArgumentException
	 */
	public static void RGB2BGR(byte[] input,int width,int height,int stride,byte[] output) 
			throws NullPointerException, IllegalArgumentException{
		if(CsCvtNativeImpl.isNativeLoaded()){
			CsCvtNativeImpl.RGB2BGR(input, width, height, stride, output);
		}else{
			CsCvtUniImpl.RGB2BGR(input, width, height, stride, output);
		}
	}
	/**
	 * 将输入图像的3字节色彩空间(RGB/BGR)反序转换
	 * @param input 输入图像矩阵(RGB/BGR),size=stride*height
	 * @param width 图像宽度
	 * @param height 图像宽度
	 * @param stride 每行步长(字节长度),必须>= width*3
	 * @throws NullPointerException 
	 * @throws IllegalArgumentException
	 */
	public static void swap3byte(byte[] input,int width,int height,int stride) 
			throws NullPointerException, IllegalArgumentException{
		if(CsCvtNativeImpl.isNativeLoaded()){
			CsCvtNativeImpl.swap3byte(input, width, height, stride);
		}else{
			CsCvtUniImpl.swap3byte(input, width, height, stride);
		}
	}
	/**
	 * 将输入图像的色彩空间RGB转为灰度，输出到output
	 * @param input 输入图像矩阵RGB,size=stride*height
	 * @param width 图像宽度
	 * @param height 图像宽度
	 * @param stride 每行步长(字节长度),必须>= width*3
	 * @param output [out] 输出图像,size=width*height
	 * @throws NullPointerException 
	 * @throws IllegalArgumentException
	 */
	public static void RGB2GRAY(byte[] input,int width,int height,int stride,byte[] output) 
			throws NullPointerException, IllegalArgumentException{
		if(CsCvtNativeImpl.isNativeLoaded()){
			CsCvtNativeImpl.RGB2GRAY(input, width, height, stride, output);
		}else{
			CsCvtUniImpl.RGB2GRAY(input, width, height, stride, output);
		}
	}
	
	/**
	 * 将输入图像的色彩空间BGR转为RGBA，输出到output
	 * @param input 输入图像矩阵BGR,size=stride*height
	 * @param width 图像宽度
	 * @param height 图像宽度
	 * @param stride 每行步长(字节长度),必须>= width*3
	 * @param output [out] 输出图像,size=width*height*4
	 * @throws NullPointerException 
	 * @throws IllegalArgumentException
	 */
	public static void BGR2RGBA(byte[] input,int width,int height,int stride,byte[] output) 
			throws NullPointerException, IllegalArgumentException{
		if(CsCvtNativeImpl.isNativeLoaded()){
			CsCvtNativeImpl.BGR2RGBA(input, width, height, stride, output);
		}else{
			CsCvtUniImpl.BGR2RGBA(input, width, height, stride, output);
		}
	}
	/**
	 * 将输入图像的色彩空间RGB转为RGBA，输出到output
	 * @param input 输入图像矩阵RGB,size=stride*height
	 * @param width 图像宽度
	 * @param height 图像宽度
	 * @param stride 每行步长(字节长度),必须>= width*3
	 * @param output [out] 输出图像,size=width*height*4
	 * @throws NullPointerException 
	 * @throws IllegalArgumentException
	 */
	public static void RGB2RGBA(byte[] input,int width,int height,int stride,byte[] output) 
			throws NullPointerException, IllegalArgumentException{
		if(CsCvtNativeImpl.isNativeLoaded()){
			CsCvtNativeImpl.RGB2RGBA(input, width, height, stride, output);
		}else{
			CsCvtUniImpl.RGB2RGBA(input, width, height, stride, output);
		}
	}
	
	/**
	 * 将输入图像 顺时针原地旋转(In-place matrix transposition)指定的角度<br>
	 * 图像必须是1字节对齐，多字节对齐的图像旋转可能会造成图像错位
	 * @param input 输入图像矩阵,size=width*height*bpp
	 * @param width 图像宽度
	 * @param height 图像宽度
	 * @param bpp 每像素字节数(1,2,3,4)
	 * @param angle 顺时针旋转角度(0,90,180,270)
	 * @throws NullPointerException
	 * @throws IllegalArgumentException
	 */
	public static void rotate(byte[] input,int width,int height,int bpp,int angle) 
			throws NullPointerException, IllegalArgumentException{
		if(CsCvtNativeImpl.isNativeLoaded()){
			CsCvtNativeImpl.rotate(input, width, height, bpp, angle);
		}else{
			CsCvtUniImpl.rotate(input, width, height, bpp, angle);
		}
	}
	/**
	 * 图像水平原地翻转(In-place)<br>
	 * 图像必须是1字节对齐，多字节对齐的图像旋转可能会造成图像错位
	 * @param input 输入图像矩阵,size=width*height*bpp
	 * @param width
	 * @param height
	 * @param bpp 每像素字节数(1,2,3,4)
	 * @throws NullPointerException
	 * @throws IllegalArgumentException
	 */
	public static void hflip(byte[] input,int width,int height,int bpp) 
			throws NullPointerException, IllegalArgumentException{
		if(CsCvtNativeImpl.isNativeLoaded()){
			CsCvtNativeImpl.hflip(input, width, height, bpp);
		}else{
			CsCvtUniImpl.hflip(input, width, height, bpp);
		}
	}
	/**
	 * 图像垂直翻转<br>
	 * 图像必须是1字节对齐，多字节对齐的图像旋转可能会造成图像错位
	 * @param input 输入图像矩阵,size=width*height*bpp
	 * @param width
	 * @param height
	 * @param bpp 每像素字节数(1,2,3,4)
	 * @throws NullPointerException
	 * @throws IllegalArgumentException
	 */
	public static void vflip(byte[] input,int width,int height,int bpp) 
			throws NullPointerException, IllegalArgumentException{
		if(CsCvtNativeImpl.isNativeLoaded()){
			CsCvtNativeImpl.vflip(input, width, height, bpp);
		}else{
			CsCvtUniImpl.vflip(input, width, height, bpp);
		}
	}
}
